<?php
/**
 * @author Eugenio Fage
 * http://eugeniofage.wordpress.com/
 * http://code.google.com/p/monky/
 * 
 */
class Comment extends AppModel {
	var $name = 'Comment';
	var $validate = array(
		'content' => array(
			'lenght' => array(
				'rule' => array('minLength',20),
				'allowEmpty' => false
			),
		)
	);

	var $belongsTo = array(
		'Link' => array(			
			'counterCache' => 'comment_count',
		),
		'User' => array()
	);
	
	var $hasMany = array(
		'Vote'=>array(
	 		'conditions' => array('Vote.type' => 'comments')
		)
	);

	public function __construct($id = false, $table = null, $ds = null) {
		$this->actsAs[]='Tree';		
		parent::__construct($id = false, $table = null, $ds = null);
	}
	
	function setCanVoteComments($comments=array(),$user_id=null){
		if(!$user_id) $logged=false;
		
		foreach ($comments as $i=>$c){
			$comments[$i]['Comment']['isVotable']=true;
			
			try {
				$this->checkCanVote($c,$user_id);
			}catch (CommentVoteException $e){
				$comments[$i]['Comment']['isVotable']=false;
			}
		}

		return $comments;		
	}
		
	function checkCanVote($c,$user_id=null){
		if(!$user_id){
			throw new CommentVoteException(__('You must be logged in to vote',true));
		}elseif (empty($c)){
			throw new CommentVoteException(__('Sorry the comment doesnt exist!',true));
		}elseif($c['User']['id']==$user_id){
			throw new CommentVoteException(__('You cant vote yourself!',true));
		}elseif($this->User->field('karma',array('id',$user_id))<Configure::read('Monky.User.minKarmaForComment')){
			throw new CommentVoteException(__('You need more karma for vote comments',true));
		}elseif($this->Vote->userHasVoteComment($c['Comment']['id'],$user_id)){
			throw new CommentVoteException(__('You have already vote this comment!',true));
		}if($this->Vote->getVoteCommentFreq(array('User'=>array('id'=>$user_id)))>3){ // crazy votes!
			$this->User->updateAll(array('karma'=>'User.karma - '.Configure::read('Monky.Votes.abuse_karma_decrease')),array('id'=>$vote['User']['id']));
			throw new CommentVoteException(__('easy cowboy!',true). ', ' . sprintf(__('your karma has decreased %s points',true),Configure::read('Monky.Votes.abuse_karma_decrease')));
		}
	}
	
	
	function vote($vote){
		$c=$this->find('first',array(
			'fields'=>array('Comment.id'),
			'contain'=>array('User'=>array('id'),'Link'=>array('id')),
			'conditions'=>array('Comment.id'=>$vote['Comment']['id'])
		));
		
		if($vote['User']['vote']<0){
			$vote['User']['vote']=-1;
		}else{
			$vote['User']['vote']=1;
		}
		
		$this->checkCanVote($c,$vote['User']['id']);
				
		
		$this->addCommentVote($vote);
		
		$this->id=$vote['Comment']['id'];
		$this->recursive=-1;
		$updated=$this->read(array('id','votes','karma'));
		return $updated;		
	}
	
	function getAffinity($iduser,$affinity=array()){
		$qry= $this->find('all',array(
			'fields'=>array('GROUP_CONCAT(Comment.id) idlist'),
			'conditions'=>array( 
				'Comment.user_id'=>$iduser, 
				'Comment.created > date_sub(now(), interval 3 day)', 
				'Comment.votes >'=> 2
			),'recursive'=>-1
		));
		
		if(empty($qry)){
			return $affinity;
		}
		
		$ids=$qry[0][0]['idlist'];
		$ncomments = substr_count($ids, ',')+1;
		if ($ncomments <= 4) {
			return $affinity;
		}

		$votes = $this->Vote->find('all',array(
			'fields'=>array('Vote.user_id','sum(Vote.value/abs(Vote.value)) as `count`'),
			'conditions'=>array('Vote.link_id'=>explode(',', $ids),'Vote.type'=>'comments'),
			'group'=>'Vote.user_id',
			'recursive'=>-1
		));
		
		foreach ($votes as $vote) {
			$user_id=$vote['Vote']['user_id'];
			$count=$vote['count'];
			if ($user_id > 0 && $user_id != $iduser && abs($count) > max(1, $ncomments/10) ) {
				$w = min(1, $ncomments/15);
				$w = max(0.5, $w);
				$c = $count/$ncomments * $w;
				if ($count > 0) {
					$a = round((1 - $c)*100);
					if (!isset($affinity[$user_id]) || $a < $affinity[$user_id]) {
						$affinity[$user_id] = $a;
					}
				} else {
					$a = round((-1 - $c)*100); 
					if (!isset($affinity[$user_id]) || ($affinity[$user_id] < 0 && $a > $affinity[$user_id]) ) {
						$affinity[$user_id] = $a;
					}
				}
			}
		}
		return $affinity;
	}
	
	
	private function addCommentVote($vote){
		$tb=$this->Vote->tablePrefix.$this->Vote->table;
		
		//dont add negatives anon votes
				
		$addQry=$this->query("INSERT HIGH_PRIORITY INTO $tb (`type`, `user_id`, `link_id`, `value`, `ip`, `created`) VALUES 
		  ('comments', ".$vote['User']['id'].", ".$vote['Comment']['id'].",	".$vote['User']['vote'].", ".Visitor::ip_int().", CURRENT_TIMESTAMP )");
		
		if(!$addQry){
			throw new ErrorVoteException(null,__('couldnt add vote',true));
		} 
				
		$this->_incrementVotes($vote);
	}
	
	
	private function _incrementVotes($vote){
		$karma='+';
		if($vote['User']['vote']<0){
			$karma='-';
		}
		$karma.=$this->User->field('karma',array('id'=>$vote['User']['id']));
		
		$this->updateAll(array('votes'=>'votes+1','karma'=>'karma'.$karma),array('id'=>$vote['Comment']['id']),-1);
				
	}
	
}
